home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 5
/
Skunkware 5.iso
/
src
/
X11
/
xarchie-2.0.9
/
weight.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-18
|
6KB
|
243 lines
/*
* weight.c : Routines for ordering hosts by "weight"
*
* George Ferguson, ferguson@cs.rochester.edu, 23 Apr 1993.
* Based on a suggestion from Peter J Nilsson (pjn@ida.liu.se).
* 13 May 1993: Add "org" to US weights and make sure others have proper
* US lists.
* 7 Jun 1993: Added weights for Norway, from janl@ifi.uio.no.
* 30 Jun 1993: Added weights for France, from Hugues.Leroy@irisa.fr
* Added weights for Germany, Volker.Zink@inf-wiss.uni-konstanz.de
* 27 Jul 1993: Added weights for Israel, from amoss@cs.huji.ac.il
*/
#include <stdio.h>
#include "sysdefs.h"
#include "stringdefs.h"
#include "xtypes.h"
#include "appres.h"
#include "weight.h"
#include "hostname.h"
#include "debug.h"
#define Number(arr) (sizeof(arr) / sizeof(arr[0]))
#define ISSPACE(C) ((C) == ' ' || (C) == '\t' || (C) == '\n')
#define ISDIGIT(C) ((C) >= '0' && (C) <= '9')
#define UNKNOWN_WEIGHT 99
/*
* Functions defined here:
*/
void initHostWeights(),reinitHostWeights();
int hostWeight();
static int parseHostWeights();
/*
* Data defined here:
*/
static HostWeightRec *hostWeightList;
static int hostWeightListLen;
/*
* These weight lists are used if the hostWeights resource isn't given.
* We attempt to determine a useful one by looking at the last component
* of the hostname, if there is one.
* The formatting is ugly so we don't have extra spaces on the Settings
* panel.
*/
static struct _HostWeightDefault {
char *domain;
char *weights;
} defaults[] = {
/* North America, from gf (also used as default) */
{ "us", "1 edu com net gov mil us org\n\
2 ca\n\
3 uk de nl fi fr eu.net\n\
100 au nz jp" },
/* For Sweden, from Peter J Nilsson (pjn@ida.liu.se) */
{ "se", "1 se\n\
2 fi dk no\n\
10 eu.net nl fr de\n\
20 edu com gov net mil us org\n\
100 au nz jp" },
/* For Norway, from gf (based on se) */
{ "no", "1 no\n\
2 fi dk se\n\
10 eu.net nl fr de\n\
20 edu com gov net mil us org\n\
100 au nz jp" },
/* For Finland, from gf (based on se) */
{ "fi", "1 si\n\
2 se dk no\n\
10 eu.net nl fr de\n\
20 edu com gov net mil us org\n\
100 au nz jp" },
/* For the UK, from gf */
{ "uk", "1 uk\n\
2 se fi dk no nl fr de eu.net\n\
20 edu com gov net mil us org\n\
100 au nz jp" },
/* For New Zealand, from Andy.Linton@comp.vuw.ac.nz */
{ "nz", "1 nz\n\
10 edu com gov net mil us org jp\n\
20 se fi dk no nl fr de eu.net uk au" },
/* For Australia, from gf (based on nz) */
{ "au", "1 au\n\
10 edu com gov net mil us org jp\n\
20 se fi dk no nl fr de eu.net uk nz" },
/* For Japan, from gf (a total guess) */
{ "jp", "1 jp\n\
10 edu com gov net mil us org\n\
20 au nz\
30 se fi dk no nl fr de eu.net uk" },
/* For Norway, from janl@ifi.uio.no */
{ "no", "1 no\n\
2 fi dk se\n\
10 eu.net nl fr\n\
20 edu com gov net de\n\
100 au nz jp" },
/* For France, from Hugues.Leroy@irisa.fr */
{ "fr", "1 fr\n\
2 se fi dk no nl uk de eu.net\n\
20 edu com gov net mil us org\n\
100 au nz jp" },
/* For Germany, from Volker.Zink@inf-wiss.uni-konstanz.de, modified with
comments from liebe@hrz.th-darmstadt.de. */
{ "de", "1 de\n\
2 ch uk dk nl fr eu.net\n\
10 se fi no\n\
20 edu com gov net mil us\n\
100 au nz jp" },
/* For Israel, from amoss@cs.huji.ac.il */
{ "il", "1 il\n\
2 ch it\n\
10 uk dk nl fr fi se no eu.net\n\
20 de cs es\n\
50 edu com gov net mil us ca\n\
100 au nz jp" },
};
/* - - - - - - - - */
void
initHostWeights()
{
char *hostname,*dot;
int i,found;
if (appResources.hostWeights == NULL) {
found = 0; /* default if none matches */
hostname = GetHostname();
if ((dot=rindex(hostname,'.')) != NULL) {
dot += 1;
for (i=0; i < Number(defaults); i++) {
if (strcasecmp(dot,defaults[i].domain) == 0) {
found = i;
break;
}
}
}
appResources.hostWeights = XtNewString(defaults[found].weights);
}
reinitHostWeights();
}
/*
* This function is called whenever the weight list changes, eg, on
* the Settings panel as well as at startup.
*/
void
reinitHostWeights()
{
/* Count how many entries there are */
hostWeightListLen = parseHostWeights(appResources.hostWeights,0);
/* Allocate the array to store them */
if (hostWeightList != NULL)
free((char*)hostWeightList);
hostWeightList = (HostWeightRec *)calloc(hostWeightListLen,
sizeof(HostWeightRec));
/* Rescan and parse for real */
(void)parseHostWeights(appResources.hostWeights,1);
}
/*
* Classes are of the form "[weight] host [host] [host] {,\n\0}"
*/
/* Each class of hosts is separated by this: */
#define ISCLASSSEP(C) ((C) == ',' || (C) == '\n')
/* Within classes, each host is separated by this: */
#define ISHOSTSEP(C) ISSPACE(C)
static int
parseHostWeights(s,saveit)
char *s;
int saveit;
{
char buf[256];
int i,n,weight;
n = 0;
weight = 0;
while (*s) {
/* Skip spaces and empty classes */
while (ISSPACE(*s) || ISCLASSSEP(*s))
s += 1;
/* Get the weight, if given */
i = 0;
while (ISDIGIT(*s))
buf[i++] = *s++;
buf[i] = '\0';
if (saveit && i > 0) {
weight = atoi(buf);
}
/* Get the hosts in the class */
while (*s && !ISCLASSSEP(*s)) {
/* Skip spaces, if any */
while (ISSPACE(*s) || ISHOSTSEP(*s))
s += 1;
/* Get the host string */
i = 0;
while (*s && !ISHOSTSEP(*s) && !ISCLASSSEP(*s))
buf[i++] = *s++;
buf[i] = '\0';
/* Save this host */
if (saveit && i > 0) {
XtFree(hostWeightList[n].name);
hostWeightList[n].name = XtMalloc(strlen(buf)+1);
strcpy(hostWeightList[n].name,buf);
hostWeightList[n].weight = weight;
DEBUG2("Set weight of \"%s\" = %d\n",buf,weight);
}
/* Keep track of how many */
n += 1;
}
}
/* Return total hosts */
return(n);
}
int
hostWeight(host)
char *host;
{
int i,offs,hostlen;
hostlen = strlen(host);
for (i=0; i < hostWeightListLen; i++) {
if ((offs=hostlen-strlen(hostWeightList[i].name)) < 0)
offs = 0;
if (!strcasecmp(host+offs,hostWeightList[i].name)) {
DEBUG3("Weight of \"%s\" (\"%s\") = %d\n",
host,host+offs,hostWeightList[i].weight);
return(hostWeightList[i].weight);
}
}
return(UNKNOWN_WEIGHT);
}